package org.onion.pattern.event.spring.outbox;


import org.apache.commons.collections.CollectionUtils;
import org.onion.pattern.event.outbox.OutboxEventConverter;
import org.onion.pattern.event.outbox.converter.DefaultOutboxEventConverter;
import org.onion.pattern.event.outbox.data.OutboxEventInfo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Component
public class OutboxEventConverterBundle implements OutboxEventConverter, BeanPostProcessor {

    @Autowired(required = false)
    private List<OutboxEventConverter> converters = new ArrayList<>();

    @Override
    public boolean support(Object event) {
        return findSupport(event).isPresent();
    }

    public Optional<OutboxEventConverter> findSupport(Object event) {
        if (CollectionUtils.isEmpty(converters)) {
            return Optional.empty();
        }
        for (OutboxEventConverter converter : converters) {
            if (converter.support(event)) {
                return Optional.of(converter);

            }
        }
        return Optional.empty();
    }

    public Optional<OutboxEventConverter> findSupport(OutboxEventInfo event) {
        if (CollectionUtils.isEmpty(converters)) {
            return Optional.empty();
        }
        for (OutboxEventConverter converter : converters) {
            if (converter.support(event)) {
                return Optional.of(converter);

            }
        }
        return Optional.empty();
    }

    @Override
    public OutboxEventInfo convert(Object event) {
        OutboxEventConverter outboxEventConverter = findSupport(event).orElse(null);
        if (outboxEventConverter == null) {
            throw new IllegalArgumentException("示匹配到转换器");

        }
        return outboxEventConverter.convert(event);
    }

    @Override
    public boolean support(OutboxEventInfo event) {
        return findSupport(event).isPresent();
    }

    @Override
    public Object convert(OutboxEventInfo eventInfo) {
        OutboxEventConverter outboxEventConverter = findSupport(eventInfo).orElse(null);
        if (outboxEventConverter == null) {
            throw new IllegalArgumentException("示匹配到转换器");

        }
        return outboxEventConverter.convert(eventInfo);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean == this) {
            return bean;
        }

        if (bean instanceof OutboxEventConverter) {
            if (!converters.contains(bean)) {
                converters.add((OutboxEventConverter) bean);
            }
        }

        converters.add(DefaultOutboxEventConverter.INSTANCE);

        return bean;
    }


}
